//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Diagnostics;
using System.IO;
using System.Resources;
using System.Globalization;
using System.Drawing;
using System.Collections;
using EntLibContrib.Resource.Configuration;
using EntLibContrib.Resource.Managers;

#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
#endif

namespace EntLibContrib.Resource.Tests
{
	[TestClass]
	public class XmlResourceWriterFixture
	{
		private static ResourceManagerFactory factory;
		private static ResourceManager resourceManager;
		private static string pathName;
		private static string baseName;
		private static string originalBaseName;
		private static string neutralFileName;
		private static string frenchFileName;
		private static string germanFileName;

		[ClassInitialize]
#if NUNIT
		public void Initialize()
#else
		public static void Initialize(TestContext context)
#endif
		{
			string fileName;
			FileInfo fileInfo;
			pathName = ".";
			originalBaseName = "Resources";
			baseName = "Test";
			fileName = ResourceFileName.Build(pathName, originalBaseName, CultureInfo.InvariantCulture, ResourceManagerSettings.XmlExtension);
			neutralFileName = ResourceFileName.Build(pathName, baseName, CultureInfo.InvariantCulture, ResourceManagerSettings.XmlExtension);
			fileInfo = new FileInfo(fileName);
			fileInfo.CopyTo(neutralFileName, true);
			fileName = ResourceFileName.Build(pathName, originalBaseName, new CultureInfo("fr"), ResourceManagerSettings.XmlExtension);
			frenchFileName = ResourceFileName.Build(pathName, baseName, new CultureInfo("fr"), ResourceManagerSettings.XmlExtension);
			fileInfo = new FileInfo(fileName);
			fileInfo.CopyTo(frenchFileName, true);
			fileName = ResourceFileName.Build(pathName, originalBaseName, new CultureInfo("de"), ResourceManagerSettings.XmlExtension);
			germanFileName = ResourceFileName.Build(pathName, baseName, new CultureInfo("de"), ResourceManagerSettings.XmlExtension);
			fileInfo = new FileInfo(fileName);
			fileInfo.CopyTo(germanFileName, true);
			factory = new ResourceManagerFactory(TestConfigurationSource.GenerateConfiguration());
			resourceManager = factory.Create("AssemblyResourceManager");
		}

		[TestCleanup]
		public void DeleteResource()
		{
		}

		[TestMethod]
		public void CreateXmlResourceWriter()
		{
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			Assert.IsNotNull(xmlResourceWriter);
			xmlResourceWriter.Close();
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException))]
		public void CreateXmlResourceWriterWithNullFileName()
		{
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter((Stream)null);
			Assert.Fail();
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException))]
		public void CreateXmlResourceWriterWithEmptyFileName()
		{
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(String.Empty);
			Assert.Fail();
		}

		[TestMethod]
		public void AddNeutralString ()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			xmlResourceWriter.AddResource("Ewdev", resourceManager["Ewdev"]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddNeutralInteger ()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			xmlResourceWriter.AddResource("TestInteger", resourceManager["TestInteger", typeof(System.Int32)]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddNeutralIcon ()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			xmlResourceWriter.AddResource("TestIcon", resourceManager["TestIcon", typeof(Icon)]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddNeutralImage ()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			xmlResourceWriter.AddResource("TestImage", resourceManager["TestImage", typeof(Bitmap)]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddNeutralAudio ()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			UnmanagedMemoryStream ums = (UnmanagedMemoryStream)resourceManager["TestSound", typeof(UnmanagedMemoryStream)];
			byte[] buffer = new byte[ums.Length];
			ums.Read(buffer, 0 ,(int)ums.Length);
			xmlResourceWriter.AddResource("TestSound", buffer);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddNeutralByteArray()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			byte[] byteArray = SerializationUtility.ToBytes(resourceManager["TestImage", typeof(Bitmap)]);
			xmlResourceWriter.AddResource("TestByteArray", byteArray);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddFrenchString ()
		{
			resourceManager.CultureInfo = new CultureInfo("fr");
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(frenchFileName);
			xmlResourceWriter.AddResource("TestString", resourceManager["TestString"]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddFrenchInteger ()
		{
			resourceManager.CultureInfo = new CultureInfo("fr");
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(frenchFileName);
			xmlResourceWriter.AddResource("TestInteger", resourceManager["TestInteger", typeof(System.Int32)]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddFrenchImage ()
		{
			resourceManager.CultureInfo = new CultureInfo("fr");
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(frenchFileName);
			xmlResourceWriter.AddResource("TestImage", resourceManager["TestImage", typeof(Bitmap)]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddGermanString ()
		{
			resourceManager.CultureInfo = new CultureInfo("de");
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(germanFileName);
			xmlResourceWriter.AddResource("TestString", resourceManager["TestString"]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddGermanInteger ()
		{
			resourceManager.CultureInfo = new CultureInfo("de");
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(germanFileName);
			xmlResourceWriter.AddResource("TestInteger", resourceManager["TestInteger", typeof(System.Int32)]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddGermanImage ()
		{
			resourceManager.CultureInfo = new CultureInfo("de");
			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(germanFileName);
			xmlResourceWriter.AddResource("TestImage", resourceManager["TestImage", typeof(Bitmap)]);
			xmlResourceWriter.Close();
			XmlResourceSet resourceSet = new XmlResourceSet(pathName, baseName, resourceManager.CultureInfo);
			Assert.AreEqual(1, resourceSet.Count);
		}

		[TestMethod]
		public void AddNeutralResourceDataNode()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			string name = "TestDataNode";
			object value = "Test Data Node";
			string typeName = value.GetType().AssemblyQualifiedName;

			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			ResourceDataNode writeDataNode = new ResourceDataNode(name, value);
			xmlResourceWriter.AddResource(name, writeDataNode);
			xmlResourceWriter.Close();

			XmlResourceReader xmlResourceReader = new XmlResourceReader(pathName, baseName, resourceManager.CultureInfo);
			xmlResourceReader.UseDataNodes = true;
			xmlResourceReader.GetEnumerator();
			string actualTypeName = "";
			object actualValue = String.Empty;
			IDictionaryEnumerator enumerator = xmlResourceReader.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ResourceDataNode readDataNode = (ResourceDataNode)enumerator.Value;
				if (readDataNode.Name == name)
				{
					actualTypeName = readDataNode.TypeName;
					actualValue = readDataNode.Value;
					break;
				}
			}
			Debug.WriteLine(name + ": type = " + actualTypeName + " value = " + actualValue);
			Assert.AreEqual(typeName, actualTypeName);
			Assert.AreEqual(value.ToString(), actualValue.ToString());
		}

		[TestMethod]
		public void AddNeutralStringWithComment()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			string name = "Ewdev";
			object value = resourceManager[name];
			string typeName = value.GetType().AssemblyQualifiedName;
			string comment = "This is a Test";

			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			ResourceDataNode writeDataNode = new ResourceDataNode(name, value);
			writeDataNode.Comment = comment;
			xmlResourceWriter.AddResource(name, writeDataNode);
			xmlResourceWriter.Close();

			XmlResourceReader xmlResourceReader = new XmlResourceReader(pathName, baseName, resourceManager.CultureInfo);
			xmlResourceReader.UseDataNodes = true;
			xmlResourceReader.GetEnumerator();
			string actualComment = "";
			string actualTypeName = "";
			object actualValue = String.Empty;
			IDictionaryEnumerator enumerator = xmlResourceReader.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ResourceDataNode readDataNode = (ResourceDataNode)enumerator.Value;
				if (readDataNode.Name == name)
				{
					actualComment = readDataNode.Comment;
					actualTypeName = readDataNode.TypeName;
					actualValue = readDataNode.Value;
					break;
				}
			}
			Debug.WriteLine(name + ": type = " + actualTypeName + " value = " + actualValue + " comment = " + actualComment);
			Assert.AreEqual(typeName, actualTypeName);
			Assert.AreEqual(value.ToString(), actualValue.ToString());
			Assert.AreEqual(comment, actualComment);
		}

		[TestMethod]
		public void AddNeutralFileRef()
		{
			resourceManager.CultureInfo = CultureInfo.InvariantCulture;
			string name = "TestFileRef";
			string typeName = typeof(ResourceFileRef).AssemblyQualifiedName;
			string fileName = "test.bmp";
			string fileType = typeof(Bitmap).AssemblyQualifiedName;
			string comment = "This is a Test File Ref";
			ResourceFileRef resourceFileRef = new ResourceFileRef(fileName, fileType);

			XmlResourceWriter xmlResourceWriter = new XmlResourceWriter(neutralFileName);
			ResourceDataNode writeDataNode = new ResourceDataNode(name, resourceFileRef);
			writeDataNode.Comment = comment;
			xmlResourceWriter.AddResource(name, writeDataNode);
			xmlResourceWriter.Close();

			XmlResourceReader xmlResourceReader = new XmlResourceReader(pathName, baseName, resourceManager.CultureInfo);
			xmlResourceReader.UseDataNodes = true;
			string actualComment = "";
			string actualTypeName = "";
			ResourceFileRef actualValue = null;
			string actualFileName = String.Empty;
			string actualFileType = String.Empty;
			IDictionaryEnumerator enumerator = xmlResourceReader.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ResourceDataNode readDataNode = (ResourceDataNode)enumerator.Value;
				if (readDataNode.Name == name)
				{
					actualComment = readDataNode.Comment;
					actualTypeName = readDataNode.TypeName;
					actualValue = (ResourceFileRef)readDataNode.FileRef;
					actualFileName = actualValue.FileName;
					actualFileType = actualValue.TypeName;
					break;
				}
			}
			Debug.WriteLine(name + ": type = " + actualTypeName + " filename = " + actualFileName + " filetype = " + actualFileType + " comment = " + actualComment);
			Assert.AreEqual(typeName, actualTypeName);
			Assert.AreEqual(fileName, actualFileName);
			Assert.AreEqual(fileType, actualFileType);
			Assert.AreEqual(comment, actualComment);
		}
	}
}
